﻿using System;
using System.Collections.Generic;
using System.Xml.Linq;
using GameEngine.Model.Data;
using GameEngine.Model.Data.implementation;
using PureMVC.Patterns;
using GameEngine.Libs;

namespace GameEngine.Model
{
    /// <summary>
    /// </summary>
    public class ViewDataProxy<MyIdType> : DataProxy, IViewDataProxy<MyIdType>
        where MyIdType : IComparable<MyIdType>
    {
        public string Name {
            get { return ProxyName; }
        }

        public IViewVO<MyIdType> VO
        {
            get { return this.Data as IViewVO<MyIdType>; }
        }

        public IViewVOId<MyIdType> Id { get { return VO.Id; } }

        public ViewDataProxy(IViewVO<MyIdType> vo)
            : base(IViewDataProxyConstants<MyIdType>.CreateDataProxyName(vo), vo)
        {
        }

        //public void LoadFromXML(XDocument doc)
        //{
        //    /*TODO List<List<ITileVO>> tiles = new List<List<ITileVO>>();
        //    foreach (XElement row in doc.Elements("tiles").Nodes())
        //    {
        //        List<ITileVO> tileRow = new List<ITileVO>();
        //        foreach (XElement tile in row.Nodes())
        //        {
        //            ITileVO tileVO = new MyTileVO();
        //            tileVO.Height = float.Parse(tile.Attribute("height").Value);
        //            foreach (XElement node in tile.Nodes())
        //                switch (node.Name.ToString())
        //                {
        //                    case "position":
        //                        tileVO.Position = new Point(
        //                            int.Parse(node.Attribute("x").Value),
        //                            int.Parse(node.Attribute("y").Value));
        //                        break;
        //                }
        //            tileRow.Add(tileVO);
        //        }
        //        tiles.Add(tileRow);
        //    }
        //    Map.Tiles = tiles;
        //    SendNotification(TILESUPDATED_NOTIFICATION, this);*/
        //}

        //public XDocument SaveToXML()
        //{
        //    return null;
        //    /*TODO
        //    XDocument doc = new XDocument();
        //    XElement mapNode = new XElement("map");
        //    XElement maxHeight = new XElement("maxHeight") { Value = Map.MaxHeight.ToString() };
        //    mapNode.Add(maxHeight);
        //    XElement size = new XElement("size");
        //    size.SetAttributeValue("x", Map.Size.X);
        //    size.SetAttributeValue("y", Map.Size.Y);
        //    mapNode.Add(size);
        //    XElement tileSize = new XElement("tileSize");
        //    tileSize.SetAttributeValue("x", Map.TileSize.X);
        //    tileSize.SetAttributeValue("y", Map.TileSize.Y);
        //    mapNode.Add(tileSize);
        //    //todo Camera
        //    XElement tilesNode = new XElement("tiles");
        //    foreach (List<ITileVO> tiles in Map.Tiles)
        //    {
        //        XElement rowNode = new XElement("row");
        //        foreach (ITileVO tile in tiles)
        //        {
        //            XElement tileNode = new XElement("tile");
        //            tileNode.SetAttributeValue("height", tile.Height.ToString());
        //            XElement position = new XElement("position");
        //            position.SetAttributeValue("x", tile.Position.X);
        //            position.SetAttributeValue("y", tile.Position.Y);
        //            tileNode.Add(position);
        //            rowNode.Add(tileNode);
        //        }
        //        tilesNode.Add(rowNode);
        //    }
        //    mapNode.Add(tilesNode);
        //    doc.Add(mapNode);
        //    return doc;*/
        //}
        
        public void AddShape(IShapeVO shape) 
        {
            if (!VO.Shapes.ContainsKey(IViewVOConstants.DefaultState))
                VO.Shapes.Add(IViewVOConstants.DefaultState, new Dictionary<IShapeVOId, IShapeVO>());
            VO.Shapes[IViewVOConstants.DefaultState].Add(shape.Id, shape);
            SendNotification(IViewDataProxyConstants<MyIdType>.THINGTYPECVIEWHANGED_NOTIFICATION, this);
        }

        public void AddShape(IShapeVO shape, ViewStateVO state)
        {
            if (!VO.Shapes.ContainsKey(state))
                VO.Shapes.Add(state, new Dictionary<IShapeVOId, IShapeVO>());
            VO.Shapes[state].Add(shape.Id, shape);

            SendNotification(IViewDataProxyConstants<MyIdType>.THINGTYPECVIEWHANGED_NOTIFICATION, this);
        }

        public void RemoveShape(IShapeVOId shapeId)
        {
            if (VO.Shapes.ContainsKey(IViewVOConstants.DefaultState))
            {
                VO.Shapes[IViewVOConstants.DefaultState].Remove(shapeId);
                SendNotification(IViewDataProxyConstants<MyIdType>.THINGTYPECVIEWHANGED_NOTIFICATION, this);
            }
        }

        public void RemoveShape(IShapeVOId shapeId, ViewStateVO state)
        {
            //if (VO.Shapes.ContainsKey(state))
            {
                VO.Shapes[state].Remove(shapeId);
                SendNotification(IViewDataProxyConstants<MyIdType>.THINGTYPECVIEWHANGED_NOTIFICATION, this);
            }
        }

        public void UpdateShape(IShapeVOId shapeId, string value)
        {
            if (VO.Shapes.ContainsKey(IViewVOConstants.DefaultState))
            {
                VO.Shapes[IViewVOConstants.DefaultState][shapeId].TypeModifiers = value;
                SendNotification(IViewDataProxyConstants<MyIdType>.THINGTYPECVIEWHANGED_NOTIFICATION, this);
            }
        }

        public void UpdateShape(IShapeVOId shapeId, string value, ViewStateVO state)
        {
            //if (VO.Shapes.ContainsKey(state))
            {
                VO.Shapes[state][shapeId].TypeModifiers = value;
                SendNotification(IViewDataProxyConstants<MyIdType>.THINGTYPECVIEWHANGED_NOTIFICATION, this);
            }
        }

        //public override string Serialize()
        //{
        //    return Serializer.Serialize(this);
        //}
    }
}